这是一个不简单的 java 序列化的错误。
先来看看日志:
|
|
项目中用到的日志管理是腾讯的 bugly。从日记中能一眼发现问题还是比较有难度的:
第一次找到的信息
|
|
根据第二行的提示我们找到 Parcel 类中的 writeSerializable
方法
|
|
接着我们找到 ObjectOutputStream
这个类、看看它的构造方法:
|
|
接着我们找到日志中出现的几个方法 writeObject
和 defaultWriteFields
、writeSerialData
我就不贴源码了
writeObject -> writeObject0 -> writeOrdinaryObject
:写入对象writeObject0 :Underlying writeObject/writeUnshared implementation.
实现基本的写对象共享问题[不知道怎么理解、就这样理解吧]writeOrdinaryObject:这个方法是被 writeObject0 方法调用的
:写入一个可序列号对象流defaultWriteFields
获取并写入给定对象的可序列化字段的值writeSerialData :Writes instance data for each serializable class of given object, from superclass to subclass.
:从父类写入给定对象的每个可序列化类的实例数据到子类[不知道怎么翻译、大佬们别打我]。
第二次
其实经过前一次的排查、心里基本有点 B Number 了、Java 层的 serializable
序列化问题出错了、是啥数据?带着这个问题找到代码中序列号的数据:
|
|
对、就这些数据、如果出错也就是这个 list 了。 看日志 12 行、这里我们又回到了 Parcel 类中的 writeSerializable
方法、这里不去扒源码了、简单的走下流程就是下面这样的:
writeArrayMapInternal -> writeValue -> writeSerializable
说到底就是数据没有序列化成功。
第三次
其实找到这里整个人都崩溃了、有没有 98 年的雪碧、给我来一打、因为自己根本就没有思路来、完全找不到路了。人人处处是惊喜、就在这时、我们项目中的大佬不知道经过了怎样的坎坷(可能是买肉了)、终于找到了问题的根本所在、给他 10086 个赞。
信息就在日志第一句
|
|
请注意看 POIMapActivity$3
中的 $3
、啥意思呢:就是说它表示POIMapActivity
类中第三个动态产生的对象。
mPoiSearch.setOnGetPoiSearchResultListener(new OnGetPoiSearchResultListener()
:地图热点搜索监听BaiduMap.OnMarkerClickListener onMarkerClickListener = new BaiduMap.OnMarkerClickListener()
:地图标记物点击监听widget.setShootingListener(new SheetViewWidget.ShootingListener()
:组件点击监听
问题就是说 SheetViewWidget.ShootingListener
这个监听在序列化的时候没成功、问题的关键是:在序列化的时候 widget
这个监听对象每次都是 new
的导致报错。
处理方法:
- 判断当监听对象为空时不处理事件
- 这个控件是使用的第三方库、监听接口抽离出来